home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-16 | 4.8 KB | 177 lines | [TEXT/PJMM] |
- { CopyBeep ©1992 Gregory M. Robbins 3/92 }
- { 3/92 v 1.0 }
- { 5/92 v 1.1 plays snd resource }
-
- UNIT CopyBeep;
- INTERFACE
-
- USES
- Processes, Traps, Sound;
- PROCEDURE main;
-
- IMPLEMENTATION
-
- PROCEDURE CloseWindowPatch (theWindowPtr: WindowPeek);
- forward;
-
- PROCEDURE ShowWindowPatch (theWindowPtr: WindowPeek);
- forward;
-
- PROCEDURE storage;
- forward;
-
- FUNCTION Gestalt (selector: OSType; VAR response: LongInt): OSErr;
- { this gestalt interface takes far fewer bytes than the standard glue }
- INLINE
- $4E56, $0000, { LINK A6,#0 ; make a cushy stack frame }
- $202E, $0008, { MOVE.L $8(A6),D0 ; get the selector }
- $A1AD, { _Gestalt }
- $226E, $0004, { MOVEA.L $4(A6),A1 ; stuff the response }
- $2288, { MOVE.L A0,(A1) }
- $3D40, $000C, { MOVE.W D0,$C(A6) ; put the error code on the stack }
- $4E5E, { UNLK A6 ; back to our previously scheduled scope }
- $508F; { ADDQ.L #8,A7 ; trash them parameters }
-
- PROCEDURE main;
- VAR
- toolScratchPtr: ^Ptr;
- myHandle: Handle;
- tempAddr: Ptr;
- storagePtr: ^Ptr;
-
- delayPtr: IntegerPtr;
- delayResHandle: Handle;
-
- sndHandle: Handle;
- sndHandlePtr: LongIntPtr;
-
- gestaltResponse: LongInt;
- retCode: OSErr;
-
- BEGIN
-
- { Think Pascal points toolScratch to the start of the block }
- toolScratchPtr := Pointer($9CE);
- myHandle := RecoverHandle(toolScratchPtr^);
-
- { check if Gestalt is implemented }
- IF NGetTrapAddress(_GestaltDispatch, OSTrap) = NGetTrapAddress(_Unimplemented, ToolTrap) THEN
- Exit(main)
- ELSE
- BEGIN
- { if there's no process manager cause the system version is less than 7.0, bail }
- retCode := Gestalt(gestaltSystemVersion, gestaltResponse);
- IF (retCode <> noErr) OR (gestaltResponse < $0700) THEN
- Exit(main)
- END;
-
- { make the init float free; it must have been loaded in the System heap and locked }
- DetachResource(myHandle);
-
- { patch ShowWindow, $A915 }
- tempAddr := Pointer(NGetTrapAddress(_ShowWindow, ToolTrap));
- storagePtr := @storage;
- storagePtr^ := tempAddr;
- SetToolTrapAddress(LongInt(@ShowWindowPatch), _ShowWindow);
-
- { patch CloseWindow, $A92D }
- tempAddr := Ptr(NGetTrapAddress(_CloseWindow, ToolTrap));
- storagePtr := Pointer(LongInt(@storage) + 4);
- storagePtr^ := tempAddr;
- SetTrapAddress(LongInt(@CloseWindowPatch), _CloseWindow);
-
- { get delay value }
- delayPtr := IntegerPtr(LongInt(@storage) + 12);
- delayResHandle := Get1IndResource('DLAY', 1);
- IF delayResHandle <> NIL THEN
- BEGIN
- delayPtr^ := IntegerPtr(delayResHandle^)^;
- ReleaseResource(delayResHandle);
- END
- ELSE
- delayPtr^ := 15;
-
- { get sound resource }
- sndHandlePtr := LongIntPtr(LongInt(@storage) + 14);
- sndHandle := Get1IndResource('snd ', 1);
- sndHandlePtr^ := LongInt(sndHandle);
- IF sndHandle <> NIL THEN
- DetachResource(sndHandle);
-
- END;
-
- FUNCTION FinderIsCurrentProcess: Boolean;
- VAR
- thePSN: ProcessSerialNumber;
- thePIR: ProcessInfoRec;
- BEGIN
- FinderIsCurrentProcess := FALSE;
- WITH thePIR DO
- BEGIN
- processInfoLength := SizeOf(ProcessInfoRec);
- processName := NIL;
- processAppSpec := NIL
- END;
- IF GetCurrentProcess(thePSN) = noErr THEN
- IF GetProcessInformation(thePSN, thePIR) = noErr THEN
- IF thePIR.processSignature = 'MACS' THEN
- FinderIsCurrentProcess := TRUE;
- END;
-
- PROCEDURE ShowWindowPatch (theWindowPtr: WindowPeek);
-
- PROCEDURE ExitPatch (PP: longint);
- INLINE
- $205F, { MOVEA.L (A7)+,A0 }
- $265F, { MOVEA.L (A7)+,A3 ; compiled code preserved A3 }
- $4E5E, { UNLK A6 }
- $4ED0; { JMP (A0) }
- VAR
- tempLongIntPtr: LongIntPtr;
- BEGIN
- IF theWindowPtr^.windowKind = $14 THEN
- IF theWindowPtr^.goAwayFlag = FALSE THEN
- IF FinderIsCurrentProcess THEN
- BEGIN { store current tick count }
- tempLongIntPtr := LongIntPtr(LongInt(@storage) + 8);
- tempLongIntPtr^ := TickCount;
- END;
- ExitPatch(LongIntPtr(@storage)^);
- END;
-
- PROCEDURE CloseWindowPatch (theWindowPtr: WindowPeek);
-
- PROCEDURE ExitPatch (PP: longint);
- INLINE
- $205F, { MOVEA.L (A7)+,A0 }
- $4E5E, { UNLK A6 }
- $4ED0; { JMP (A0) }
-
- VAR
- retCode: OSErr;
- BEGIN
- IF theWindowPtr^.windowKind = $14 THEN
- IF theWindowPtr^.goAwayFlag = FALSE THEN
- IF FinderIsCurrentProcess THEN
- IF LongIntPtr(LongInt(@storage) + 8)^ + 60 * IntegerPtr(LongInt(@storage) + 12)^ < TickCount THEN { been more than 15 secs }
- IF LongIntPtr(LongInt(@storage) + 8)^ + 216000 > TickCount THEN { forget it after an hour }
- BEGIN
- IF LongIntPtr(LongInt(@storage) + 14)^ <> LongInt(NIL) THEN { play the sound }
- retCode := SndPlay(NIL, Handle(LongIntPtr(LongInt(@storage) + 14)^), false)
- ELSE { no sound resource, so just beep }
- SysBeep(20);
- END;
- ExitPatch(LongIntPtr(LongInt(@storage) + 4)^)
- END;
-
-
- PROCEDURE storage;
- { storage: ShowWindow addr; +4: CloseWindow addr; +8: tickcount at ShowWindow break; }
- { +12: min delay in seconds; +14: sndHandle }
- PROCEDURE nops;
- INLINE
- $4E71, $4E71, $4E71, $4E71, $4E71, $4E71;
- BEGIN
- nops
- END;
- END.